/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name          : eeprom.c
* Author             : MCD Application Team
* Version            : V2.0.0
* Date               : 06/16/2008
* Description        : This file provides all the EEPROM emulation firmware functions.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "eeprom.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/

const unsigned short VirtAddVarTab[NumbOfVar]= 
	{
		0x5555,0x5556,0x5557,0x5558,0x5559,0x555A,0x555B,0x555C,
		0x555D,0x555E,0x555F,0x5560,0x5561,0x5562,0x5563,0x5564,
		0x5565,0x5566,0x5567,0x5568,0x5569,0x556A,0x556B,0x556C,
		0x556D,0x556E,0x556F,0x5570,0x5571,0x5572,0x5573,0x5574,
		0x5575,0x5576,0x5577,0x5578,0x5579,0x557A,0x557B,0x557C,
		0x557D,0x557E,0x557F,0x5580,0x5581,0x5582,0x5583,0x5584,
		0x5585,0x5586,0x5587,0x5588,0x5589,0x558A,0x558B,0x558C,
		0x558D,0x558E,0x558F,0x5590,0x5591,0x5592,0x5593,0x5594,
		0x5595,0x5596,0x5597,0x5598,0x5599,0x559A,0x559B,0x559C,
		0x559D,0x559E,0x559F,0x55A0,0x55A1,0x55A2,0x55A3,0x55A4,
		0x55A5,0x55A6,0x55A7,0x55A8,0x55A9,0x55AA,0x55AB,0x55AC,
		0x55AD,0x55AE,0x55AF,0x55B0,0x55B1,0x55B2,0x55B3,0x55B4,
		0x55B5,0x55B6,0x55B7,0x55B8,0x55B9,0x55BA,0x55BB,0x55BC,
		0x55BD,0x55BE,0x55BF,0x55C0,0x55C1,0x55C2,0x55C3,0x55C4,
		0x55C5,0x55C6,0x55C7,0x55C8,0x55C9,0x55CA,0x55CB,0x55CC,
		0x55CD,0x55CE,0x55CF,0x55D0,0x55D1,0x55D2,0x55D3,0x55D4,
		0x55D5,0x55D6,0x55D7,0x55D8,0x55D9,0x55DA,0x55DB,0x55DC,
		0x55DD,0x55DE,0x55DF,0x55E0,0x55E1,0x55E2,0x55E3,0x55E4,
		0x55E5,0x55E6,0x55E7,0x55E8,0x55E9,0x55EA,0x55EB,0x55EC,
		0x55ED,0x55EE,0x55EF,0x55F0,0x55F1,0x55F2,0x55F3,0x55F4,
		0x55F5,0x55F6,0x55F7,0x55F8,0x55F9,0x55FA,0x55FB,0x55FC,
		0x55FD,0x55FE,0x55FF,0x5600,0x5601,0x5602,0x5603,0x5604,
		0x5605,0x5606,0x5607,0x5608,0x5609,0x560A,0x560B,0x560C,
		0x560D,0x560E,0x560F,0x5610,0x5611,0x5612,0x5613,0x5614,
		0x5615,0x5616,0x5617,0x5618,0x5619,0x561A,0x561B,0x561C,
		0x561D,0x561E,0x561F,0x5620,0x5621,0x5622,0x5623,0x5624,
		0x5625,0x5626,0x5627,0x5628,0x5629,0x562A,0x562B,0x562C,
		0x562D,0x562E,0x562F,0x5630,0x5631,0x5632,0x5633,0x5634,
		0x5635,0x5636,0x5637,0x5638,0x5639,0x563A,0x563B,0x563C,
		0x563D,0x563E,0x563F,0x5640,0x5641,0x5642,0x5643,0x5644,
		0x5645,0x5646,0x5647,0x5648,0x5649,0x564A,0x564B,0x564C,
		0x564D,0x564E,0x564F,0x5650,0x5651,0x5652,0x5653,0x5654,
		0x5655,0x5656,0x5657,0x5658,0x5659,0x565A,0x565B,0x565C,
		0x565D,0x565E,0x565F,0x5660,0x5661,0x5662,0x5663,0x5664,
		0x5665,0x5666,0x5667,0x5668,0x5669,0x566A,0x566B,0x566C,
		0x566D,0x566E,0x566F,0x5670,0x5671,0x5672,0x5673,0x5674,
		0x5675,0x5676,0x5677,0x5678,0x5679,0x567A,0x567B,0x567C,
		0x567D,0x567E,0x567F,0x5680,0x5681,0x5682,0x5683,0x5684,
		0x5685,0x5686,0x5687,0x5688,0x5689,0x568A,0x568B,0x568C,
		0x568D,0x568E,0x568F,0x5690,0x5691,0x5692,0x5693,0x5694,
		0x5695,0x5696,0x5697,0x5698,0x5699,0x569A,0x569B,0x569C,
		0x569D,0x569E,0x569F,0x56A0,0x56A1,0x56A2,0x56A3,0x56A4,
		0x56A5,0x56A6,0x56A7,0x56A8,0x56A9,0x56AA,0x56AB,0x56AC,
		0x56AD,0x56AE,0x56AF,0x56B0,0x56B1,0x56B2,0x56B3,0x56B4,
		0x56B5,0x56B6,0x56B7,0x56B8,0x56B9,0x56BA,0x56BB,0x56BC,
		0x56BD,0x56BE,0x56BF,0x56C0,0x56C1,0x56C2,0x56C3,0x56C4,
		0x56C5,0x56C6,0x56C7,0x56C8,0x56C9,0x56CA,0x56CB,0x56CC,
		0x56CD,0x56CE,0x56CF,0x56D0,0x56D1,0x56D2,0x56D3,0x56D4,
		0x56D5,0x56D6,0x56D7,0x56D8,0x56D9,0x56DA
                        };

/* Global variable used to store variable value in read sequence */
u16 DataVar = 0;

/* Virtual address defined by the user: 0xFFFF value is prohibited */
//extern u16 VirtAddVarTab[NumbOfVar];

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
static FLASH_Status EE_Format(void);
static u16 EE_FindValidPage(u8 Operation);
static u16 EE_VerifyPageFullWriteVariable(u16 VirtAddress, u16 Data);
static u16 EE_PageTransfer(u16 VirtAddress, u16 Data);


void EEPROM_DataInit(void)
{
	uint8_t i;
	
	//FLASH_Unlock();	
	 
	//??????
	for(i=0;i<EE_MAX_SN_LEN;i++)
	{
		EE_WriteVariable(VirtAddVarTab[EE_SN_START+i],0x20);						
	}
	
	//???EEPROM?
	for(i=0;i<EE_MAX_DA_LEN;i++)
	{
		EE_WriteVariable(VirtAddVarTab[EE_DA_START+i],0x00);							
	}
    /* ???????? */
    EE_WriteVariable(VirtAddVarTab[EE_EC_PO_DIR],0x00);    
	//FLASH_Lock();	
	
}



/*******************************************************************************
* Function Name  : EE_Init
* Description    : Restore the pages to a known good state in case of pages'
*                  status corruption after a power loss.
* Input          : None.
* Output         : None.
* Return         : - Flash error code: on write Flash error
*                  - FLASH_COMPLETE: on success
*******************************************************************************/
u16 EE_Init(void)
{
    u16 PageStatus0 = 6, PageStatus1 = 6;
    u16 VarIdx = 0;
    u16 EepromStatus = 0, ReadStatus = 0;
    s16 x = -1;
    u16  FlashStatus;

    /* Get Page0 status */
    PageStatus0 = (*(vu16*)PAGE0_BASE_ADDRESS);
    /* Get Page1 status */
    PageStatus1 = (*(vu16*)PAGE1_BASE_ADDRESS);

    /* Check for invalid header states and repair if necessary */
    switch (PageStatus0)
    {
    case ERASED:
        if (PageStatus1 == VALID_PAGE) /* Page0 erased, Page1 valid */
        {
            /* Erase Page0 */
            FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS);
            /* If erase operation was failed, a Flash error code is returned */
            if (FlashStatus != FLASH_COMPLETE)
            {
                return FlashStatus;
            }
        }
        else if (PageStatus1 == RECEIVE_DATA) /* Page0 erased, Page1 receive */
        {
            /* Erase Page0 */
            FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS);
            /* If erase operation was failed, a Flash error code is returned */
            if (FlashStatus != FLASH_COMPLETE)
            {
                return FlashStatus;
            }
            /* Mark Page1 as valid */
            FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, VALID_PAGE);
            /* If program operation was failed, a Flash error code is returned */
            if (FlashStatus != FLASH_COMPLETE)
            {
                return FlashStatus;
            }
        }
        else /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */
        {
            /* Erase both Page0 and Page1 and set Page0 as valid page */
            FlashStatus = EE_Format();
            /* If erase/program operation was failed, a Flash error code is returned */
            if (FlashStatus != FLASH_COMPLETE)
            {
                return FlashStatus;
            }
        }
        break;

    case RECEIVE_DATA:
        if (PageStatus1 == VALID_PAGE) /* Page0 receive, Page1 valid */
        {
            /* Transfer data from Page1 to Page0 */
            for (VarIdx = 0; VarIdx < NumbOfVar; VarIdx++)
            {
                if (( *(vu16*)(PAGE0_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
                {
                    x = VarIdx;
                }
                if (VarIdx != x)
                {
                    /* Read the last variables' updates */
                    ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
                    /* In case variable corresponding to the virtual address was found */
                    if (ReadStatus != 0x1)
                    {
                        /* Transfer the variable to the Page0 */
                        EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
                        /* If program operation was failed, a Flash error code is returned */
                        if (EepromStatus != FLASH_COMPLETE)
                        {
                            return EepromStatus;
                        }
                    }
                }
            }
            /* Mark Page0 as valid */
            FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE);
            /* If program operation was failed, a Flash error code is returned */
            if (FlashStatus != FLASH_COMPLETE)
            {
                return FlashStatus;
            }
            /* Erase Page1 */
            FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS);
            /* If erase operation was failed, a Flash error code is returned */
            if (FlashStatus != FLASH_COMPLETE)
            {
                return FlashStatus;
            }
        }
        else if (PageStatus1 == ERASED) /* Page0 receive, Page1 erased */
        {
            /* Erase Page1 */
            FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS);
            /* If erase operation was failed, a Flash error code is returned */
            if (FlashStatus != FLASH_COMPLETE)
            {
                return FlashStatus;
            }
            /* Mark Page0 as valid */
            FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE);
            /* If program operation was failed, a Flash error code is returned */
            if (FlashStatus != FLASH_COMPLETE)
            {
                return FlashStatus;
            }
        }
        else /* Invalid state -> format eeprom */
        {
            /* Erase both Page0 and Page1 and set Page0 as valid page */
            FlashStatus = EE_Format();
            /* If erase/program operation was failed, a Flash error code is returned */
            if (FlashStatus != FLASH_COMPLETE)
            {
                return FlashStatus;
            }
        }
        break;

    case VALID_PAGE:
        if (PageStatus1 == VALID_PAGE) /* Invalid state -> format eeprom */
        {
            /* Erase both Page0 and Page1 and set Page0 as valid page */
            FlashStatus = EE_Format();
            /* If erase/program operation was failed, a Flash error code is returned */
            if (FlashStatus != FLASH_COMPLETE)
            {
                return FlashStatus;
            }
        }
        else if (PageStatus1 == ERASED) /* Page0 valid, Page1 erased */
        {
            /* Erase Page1 */
            FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS);
            /* If erase operation was failed, a Flash error code is returned */
            if (FlashStatus != FLASH_COMPLETE)
            {
                return FlashStatus;
            }
        }
        else /* Page0 valid, Page1 receive */
        {
            /* Transfer data from Page0 to Page1 */
            for (VarIdx = 0; VarIdx < NumbOfVar; VarIdx++)
            {
                if ((*(vu16*)(PAGE1_BASE_ADDRESS + 6)) == VirtAddVarTab[VarIdx])
                {
                    x = VarIdx;
                }
                if (VarIdx != x)
                {
                    /* Read the last variables' updates */
                    ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
                    /* In case variable corresponding to the virtual address was found */
                    if (ReadStatus != 0x1)
                    {
                        /* Transfer the variable to the Page1 */
                        EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
                        /* If program operation was failed, a Flash error code is returned */
                        if (EepromStatus != FLASH_COMPLETE)
                        {
                            return EepromStatus;
                        }
                    }
                }
            }
            /* Mark Page1 as valid */
            FlashStatus = FLASH_ProgramHalfWord(PAGE1_BASE_ADDRESS, VALID_PAGE);
            /* If program operation was failed, a Flash error code is returned */
            if (FlashStatus != FLASH_COMPLETE)
            {
                return FlashStatus;
            }
            /* Erase Page0 */
            FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS);
            /* If erase operation was failed, a Flash error code is returned */
            if (FlashStatus != FLASH_COMPLETE)
            {
                return FlashStatus;
            }
        }
        break;

    default:  /* Any other state -> format eeprom */
        /* Erase both Page0 and Page1 and set Page0 as valid page */
        FlashStatus = EE_Format();
        /* If erase/program operation was failed, a Flash error code is returned */
        if (FlashStatus != FLASH_COMPLETE)
        {
            return FlashStatus;
        }
        break;
    }

    return FLASH_COMPLETE;
}

/*******************************************************************************
* Function Name  : EE_ReadVariable
* Description    : Returns the last stored variable data, if found, which
*                  correspond to the passed virtual address
* Input          : - VirtAddress: Variable virtual address
*                  - Data: Global variable contains the read variable value
* Output         : None
* Return         : - Success or error status:
*                      - 0: if variable was found
*                      - 1: if the variable was not found
*                      - NO_VALID_PAGE: if no valid page was found.
*******************************************************************************/
u16 EE_ReadVariable(u16 VirtAddress, u16* Data)
{
    u16 ValidPage = PAGE0;
    u16 AddressValue = 0x5555, ReadStatus = 1;
    u32 Address = 0x0803f000, PageStartAddress = 0x0803f000;

    /* Get active Page for read operation */
    ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);

    /* Check if there is no valid page */
    if (ValidPage == NO_VALID_PAGE)
    {
        return  NO_VALID_PAGE;
    }

    /* Get the valid Page start Address */
    PageStartAddress = (u32)(EEPROM_START_ADDRESS + (u32)(ValidPage * PAGE_SIZE));

    /* Get the valid Page end Address */
    Address = (u32)((EEPROM_START_ADDRESS - 2) + (u32)((1 + ValidPage) * PAGE_SIZE));

    /* Check each active page address starting from end */
    while (Address > (PageStartAddress + 2))
    {
        /* Get the current location content to be compared with virtual address */
        AddressValue = (*(vu16*)Address);

        /* Compare the read address with the virtual address */
        if (AddressValue == VirtAddress)
        {
            /* Get content of Address-2 which is variable value */
            *Data = (*(vu16*)(Address - 2));

            /* In case variable value is read, reset ReadStatus flag */
            ReadStatus = 0;

            break;
        }
        else
        {
            /* Next address location */
            Address = Address - 4;
        }
    }

    /* Return ReadStatus value: (0: variable exist, 1: variable doesn't exist) */
    return ReadStatus;
}

/*******************************************************************************
* Function Name  : EE_WriteVariable
* Description    : Writes/upadtes variable data in EEPROM.
* Input          : - VirtAddress: Variable virtual address
*                  - Data: 16 bit data to be written
* Output         : None
* Return         : - Success or error status:
*                      - FLASH_COMPLETE: on success,
*                      - PAGE_FULL: if valid page is full
*                      - NO_VALID_PAGE: if no valid page was found
*                      - Flash error code: on write Flash error
*******************************************************************************/
u16 EE_WriteVariable(u16 VirtAddress, u16 Data)
{
    u16 Status = 0;

    /* Write the variable virtual address and value in the EEPROM */
    Status = EE_VerifyPageFullWriteVariable(VirtAddress, Data);

    /* In case the EEPROM active page is full */
    if (Status == PAGE_FULL)
    {
        /* Perform Page transfer */
        Status = EE_PageTransfer(VirtAddress, Data);
    }

    /* Return last operation status */
    return Status;
}

/*******************************************************************************
* Function Name  : EE_Format
* Description    : Erases PAGE0 and PAGE1 and writes VALID_PAGE header to PAGE0
* Input          : None
* Output         : None
* Return         : Status of the last operation (Flash write or erase) done during
*                  EEPROM formating
*******************************************************************************/
static FLASH_Status EE_Format(void)
{
    FLASH_Status FlashStatus = FLASH_COMPLETE;

    /* Erase Page0 */
    FlashStatus = FLASH_ErasePage(PAGE0_BASE_ADDRESS);

    /* If erase operation was failed, a Flash error code is returned */
    if (FlashStatus != FLASH_COMPLETE)
    {
        return FlashStatus;
    }

    /* Set Page0 as valid page: Write VALID_PAGE at Page0 base address */
    FlashStatus = FLASH_ProgramHalfWord(PAGE0_BASE_ADDRESS, VALID_PAGE);

    /* If program operation was failed, a Flash error code is returned */
    if (FlashStatus != FLASH_COMPLETE)
    {
        return FlashStatus;
    }

    /* Erase Page1 */
    FlashStatus = FLASH_ErasePage(PAGE1_BASE_ADDRESS);
	
	EEPROM_DataInit();

    /* Return Page1 erase operation status */
    return FlashStatus;
}

/*******************************************************************************
* Function Name  : EE_FindValidPage
* Description    : Find valid Page for write or read operation
* Input          : - Operation: operation to achieve on the valid page:
*                      - READ_FROM_VALID_PAGE: read operation from valid page
*                      - WRITE_IN_VALID_PAGE: write operation from valid page
* Output         : None
* Return         : Valid page number (PAGE0 or PAGE1) or NO_VALID_PAGE in case
*                  of no valid page was found
*******************************************************************************/
static u16 EE_FindValidPage(u8 Operation)
{
    u16 PageStatus0 = 6, PageStatus1 = 6;

    /* Get Page0 actual status */
    PageStatus0 = (*(vu16*)PAGE0_BASE_ADDRESS);

    /* Get Page1 actual status */
    PageStatus1 = (*(vu16*)PAGE1_BASE_ADDRESS);

    /* Write or read operation */
    switch (Operation)
    {
    case WRITE_IN_VALID_PAGE:   /* ---- Write operation ---- */
        if (PageStatus1 == VALID_PAGE)
        {
            /* Page0 receiving data */
            if (PageStatus0 == RECEIVE_DATA)
            {
                return PAGE0;         /* Page0 valid */
            }
            else
            {
                return PAGE1;         /* Page1 valid */
            }
        }
        else if (PageStatus0 == VALID_PAGE)
        {
            /* Page1 receiving data */
            if (PageStatus1 == RECEIVE_DATA)
            {
                return PAGE1;         /* Page1 valid */
            }
            else
            {
                return PAGE0;         /* Page0 valid */
            }
        }
        else
        {
            return NO_VALID_PAGE;   /* No valid Page */
        }

    case READ_FROM_VALID_PAGE:  /* ---- Read operation ---- */
        if (PageStatus0 == VALID_PAGE)
        {
            return PAGE0;           /* Page0 valid */
        }
        else if (PageStatus1 == VALID_PAGE)
        {
            return PAGE1;           /* Page1 valid */
        }
        else
        {
            return NO_VALID_PAGE ;  /* No valid Page */
        }

    default:
        return PAGE0;             /* Page0 valid */
    }
}

/*******************************************************************************
* Function Name  : EE_VerifyPageFullWriteVariable
* Description    : Verify if active page is full and Writes variable in EEPROM.
* Input          : - VirtAddress: 16 bit virtual address of the variable
*                  - Data: 16 bit data to be written as variable value
* Output         : None
* Return         : - Success or error status:
*                      - FLASH_COMPLETE: on success
*                      - PAGE_FULL: if valid page is full
*                      - NO_VALID_PAGE: if no valid page was found
*                      - Flash error code: on write Flash error
*******************************************************************************/
static u16 EE_VerifyPageFullWriteVariable(u16 VirtAddress, u16 Data)
{
    FLASH_Status FlashStatus = FLASH_COMPLETE;
    u16 ValidPage = PAGE0;
    u32 Address = 0x0803f000, PageEndAddress = 0x0803ffff;

    /* Get valid Page for write operation */
    ValidPage = EE_FindValidPage(WRITE_IN_VALID_PAGE);

    /* Check if there is no valid page */
    if (ValidPage == NO_VALID_PAGE)
    {
        return  NO_VALID_PAGE;
    }

    /* Get the valid Page start Address */
    Address = (u32)(EEPROM_START_ADDRESS + (u32)(ValidPage * PAGE_SIZE));

    /* Get the valid Page end Address */
    PageEndAddress = (u32)((EEPROM_START_ADDRESS - 2) + (u32)((1 + ValidPage) * PAGE_SIZE));

    /* Check each active page address starting from begining */
    while (Address < PageEndAddress)
    {
        /* Verify if Address and Address+2 contents are 0xFFFFFFFF */
        if ((*(vu32*)Address) == 0xFFFFFFFF)
        {
            /* Set variable data */
            FlashStatus = FLASH_ProgramHalfWord(Address, Data);
            /* If program operation was failed, a Flash error code is returned */
            if (FlashStatus != FLASH_COMPLETE)
            {
                return FlashStatus;
            }
            /* Set variable virtual address */
            FlashStatus = FLASH_ProgramHalfWord(Address + 2, VirtAddress);
            /* Return program operation status */
            return FlashStatus;
        }
        else
        {
            /* Next address location */
            Address = Address + 4;
        }
    }

    /* Return PAGE_FULL in case the valid page is full */
    return PAGE_FULL;
}

/*******************************************************************************
* Function Name  : EE_PageTransfer
* Description    : Transfers last updated variables data from the full Page to
*                  an empty one.
* Input          : - VirtAddress: 16 bit virtual address of the variable
*                  - Data: 16 bit data to be written as variable value
* Output         : None
* Return         : - Success or error status:
*                      - FLASH_COMPLETE: on success,
*                      - PAGE_FULL: if valid page is full
*                      - NO_VALID_PAGE: if no valid page was found
*                      - Flash error code: on write Flash error
*******************************************************************************/
static u16 EE_PageTransfer(u16 VirtAddress, u16 Data)
{
    FLASH_Status FlashStatus = FLASH_COMPLETE;
    u32 NewPageAddress = 0x0803f7ff, OldPageAddress = 0x0803f000;
    u16 ValidPage = PAGE0, VarIdx = 0;
    u16 EepromStatus = 0, ReadStatus = 0;

    /* Get active Page for read operation */
    ValidPage = EE_FindValidPage(READ_FROM_VALID_PAGE);

    if (ValidPage == PAGE1)       /* Page1 valid */
    {
        /* New page address where variable will be moved to */
        NewPageAddress = PAGE0_BASE_ADDRESS;

        /* Old page address where variable will be taken from */
        OldPageAddress = PAGE1_BASE_ADDRESS;
    }
    else if (ValidPage == PAGE0)  /* Page0 valid */
    {
        /* New page address where variable will be moved to */
        NewPageAddress = PAGE1_BASE_ADDRESS;

        /* Old page address where variable will be taken from */
        OldPageAddress = PAGE0_BASE_ADDRESS;
    }
    else
    {
        return NO_VALID_PAGE;       /* No valid Page */
    }

    /* Set the new Page status to RECEIVE_DATA status */
    FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, RECEIVE_DATA);
    /* If program operation was failed, a Flash error code is returned */
    if (FlashStatus != FLASH_COMPLETE)
    {
        return FlashStatus;
    }

    /* Write the variable passed as parameter in the new active page */
    EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddress, Data);
    /* If program operation was failed, a Flash error code is returned */
    if (EepromStatus != FLASH_COMPLETE)
    {
        return EepromStatus;
    }

    /* Transfer process: transfer variables from old to the new active page */
    for (VarIdx = 0; VarIdx < NumbOfVar; VarIdx++)
    {
        if (VirtAddVarTab[VarIdx] != VirtAddress)  /* Check each variable except the one passed as parameter */
        {
            /* Read the other last variable updates */
            ReadStatus = EE_ReadVariable(VirtAddVarTab[VarIdx], &DataVar);
            /* In case variable corresponding to the virtual address was found */
            if (ReadStatus != 0x1)
            {
                /* Transfer the variable to the new active page */
                EepromStatus = EE_VerifyPageFullWriteVariable(VirtAddVarTab[VarIdx], DataVar);
                /* If program operation was failed, a Flash error code is returned */
                if (EepromStatus != FLASH_COMPLETE)
                {
                    return EepromStatus;
                }
            }
        }
    }

    /* Erase the old Page: Set old Page status to ERASED status */
    FlashStatus = FLASH_ErasePage(OldPageAddress);
    /* If erase operation was failed, a Flash error code is returned */
    if (FlashStatus != FLASH_COMPLETE)
    {
        return FlashStatus;
    }

    /* Set new Page status to VALID_PAGE status */
    FlashStatus = FLASH_ProgramHalfWord(NewPageAddress, VALID_PAGE);
    /* If program operation was failed, a Flash error code is returned */
    if (FlashStatus != FLASH_COMPLETE)
    {
        return FlashStatus;
    }

    /* Return last operation flash status */
    return FlashStatus;
}

/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
